﻿using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
namespace AiMoWindows.MainActions.ScriptActions.SubActions
{
    /// <summary>
    /// 对代码进行注释和取消
    /// </summary>
    class CommentScriptsAction(ActionsController owner)
    {
        readonly ActionsController owner = owner;
        public async Task CommentUncommentSelectionAsync(CommentActionType action)
        {
            const string singleLineCommentString = "//";
            Document document = owner.CurrentDocument;
            TextSpan textSpan = owner.CurrentSelectionSpan;
            SourceText documentText = await document.GetTextAsync().ConfigureAwait(false);
            List<TextChange> changes = new List<TextChange>();
            TextLine[] lines = documentText.Lines.SkipWhile(x => !x.Span.IntersectsWith(textSpan))
                .TakeWhile(x => x.Span.IntersectsWith(textSpan)).ToArray();
            if (action == CommentActionType.Comment)
            {
                int startFromLine = int.MaxValue;
                foreach (TextLine line in lines)
                {
                    int start_i = line.GetFirstNonWhitespacePosition();
                    if (start_i >= 0)
                    {
                        startFromLine = Math.Min(start_i, startFromLine);
                    }
                }
                foreach (TextLine line in lines)
                {
                    if (!string.IsNullOrWhiteSpace(documentText.GetSubText(line.Span).ToString()))
                    {
                        int start = line.Start;
                        if (line.Span.Length > startFromLine)
                        {
                            start += startFromLine;
                        }
                        changes.Add(new TextChange(new TextSpan(start, 0), singleLineCommentString));
                    }
                }
            }
            else if (action == CommentActionType.Uncomment)
            {
                foreach (var line in lines)
                {
                    var text = documentText.GetSubText(line.Span).ToString();
                    if (text.TrimStart().StartsWith(singleLineCommentString, StringComparison.Ordinal))
                    {
                        changes.Add(new TextChange(new TextSpan(
                            line.Start + text.IndexOf(singleLineCommentString, StringComparison.Ordinal),
                            singleLineCommentString.Length), string.Empty));
                    }
                }
            }
            if (changes.Count == 0) return;
            Document changedDocument = document.WithText(documentText.WithChanges(changes));
            if (action == CommentActionType.Uncomment)
            {
                Document formattedDocument = await owner.FormatAction.FormatDocumentAsync(changedDocument);
                owner.ScriptsHost.UpdateDocument(formattedDocument);
            }
            else
            {
                owner.ScriptsHost.UpdateDocument(changedDocument);
            }
        }
    }
}
